/*
 * mocp-lib.h
 * 
 * Copyright 2012 Kamil Cukrowski <kamil@dyzio.pl>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation version 2.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * 
 * based on Music On Console
 * Thank you Damian Pietras <daper@daper.net>
 * 
 */
struct event
{
	int type; /* type of the event (one of EV_*) */
	void *data; /* optional data associated with the event */
	struct event *next;
};

struct event_queue
{
	struct event *head;
	struct event *tail;
};

struct file_tags
{
	char *title;
	char *artist;
	char *album;
	int track;
	int time;
	int filled; /* Which tags are filled: TAGS_COMMENTS, TAGS_TIME. */
};

struct server_options_type
{
	int shuffle;
	int repeat;
	int autonext;
};

struct file_info {
	char *file;
	char *title;
	int bitrate;
	int rate;
	int curr_time;
	int total_time;
	int channels;
	int state; /* STATE_* */
	struct file_tags *tags;
	struct server_options_type *options;   /* repeat, shuffle ... */
};

/* Status of nonblock sending/receiving function. */
#define NB_IO_OK 0
#define NB_IO_BLOCK 1
#define NB_IO_ERR 2

/* Flags for the info decoder function. */
enum tags_select
{
	TAGS_COMMENTS   = 0x01, /* artist, title, etc. */
	TAGS_TIME       = 0x02 /* time of the file. */
};

/* Used as data field in the event queue for EV_FILE_TAGS. */
struct tag_ev_response
{
	char *file;
	struct file_tags *tags;
};



/* Definition of events send by server to the client */
#define EV_STATE  0x01 /* server has changed the state */
#define EV_CTIME  0x02 /* current time of the song has changed */
#define EV_SRV_ERROR  0x04 /* an error occured */
#define EV_BUSY   0x05 /* another client is connected to the server */
#define EV_DATA   0x06 /* data in response to a request will arrive */
#define EV_BITRATE  0x07 /* the bitrate has changed */
#define EV_RATE   0x08 /* the rate has changed */
#define EV_CHANNELS 0x09 /* the number of channels has changed */
#define EV_EXIT   0x0a /* the server is about to exit */
#define EV_PONG   0x0b /* response for CMD_PING */
#define EV_OPTIONS  0x0c /* the options has changed */
#define EV_SEND_PLIST 0x0d /* Request for sending the playlist. */
#define EV_TAGS   0x0e /* tags for the current file has changed. */
#define EV_STATUS_MSG 0x0f /* Followed by a status message */
#define EV_MIXER_CHANGE 0x10 /* the mixer channel was changed */
#define EV_FILE_TAGS  0x11 /* tags in a response for tags request */

/* Events caused by a client that wants to modify the playlist (see
 * CMD_CLI_PLIST* commands. */
#define EV_PLIST_ADD  0x50 /* add an item, followed by the file name */
#define EV_PLIST_DEL  0x51 /* delete an item, followed by the file name */
#define EV_PLIST_MOVE 0x52 /* move an item, followed by 2 file names */
#define EV_PLIST_CLEAR  0x53 /* clear the playlist */

/* State of the server. */
#define STATE_PLAY  0x01
#define STATE_STOP  0x02
#define STATE_PAUSE 0x03

/* Definition of server commands */
#define CMD_PLAY  0x00 /* play the first element on the list */
#define CMD_LIST_CLEAR  0x01 /* clear the list */
#define CMD_LIST_ADD  0x02 /* add an item to the list */
#define CMD_STOP  0x04 /* stop playing */
#define CMD_PAUSE 0x05 /* pause */
#define CMD_UNPAUSE 0x06 /* unpause */
#define CMD_SET_OPTION  0x07 /* set an option */
#define CMD_GET_OPTION  0x08 /* get an option */
#define CMD_GET_CTIME 0x0d /* get the current song time */
#define CMD_GET_SNAME 0x0f /* get the stream file name */
#define CMD_NEXT  0x10 /* start playing next song if available */
#define CMD_QUIT  0x11 /* shutdown the server */
#define CMD_SEEK  0x12 /* seek in the current stream */
#define CMD_GET_STATE 0x13 /* get the state */
#define CMD_DISCONNECT  0x15 /* disconnect from the server */
#define CMD_GET_BITRATE 0x16 /* get the bitrate */
#define CMD_GET_RATE  0x17 /* get the rate */
#define CMD_GET_CHANNELS  0x18 /* get the number of channels */
#define CMD_PING  0x19 /* request for EV_PONG */
#define CMD_GET_MIXER 0x1a /* get the volume level */
#define CMD_SET_MIXER 0x1b /* set the volume level */
#define CMD_DELETE  0x1c /* delete an item from the playlist */
#define CMD_SEND_EVENTS 0x1d /* request for events */
#define CMD_GET_ERROR 0x1e /* get the error message */
#define CMD_PREV  0x20 /* start playing previous song if available */
#define CMD_SEND_PLIST  0x21 /* send the playlist to the requesting client */
#define CMD_GET_PLIST 0x22 /* get the playlist from one of the clients */
#define CMD_CAN_SEND_PLIST  0x23 /* mark the client as able to to send
	  playlist */
#define CMD_CLI_PLIST_ADD 0x24 /* add an item to the clients playlist */
#define CMD_CLI_PLIST_DEL 0x25 /* delete an item from the clients
	  playlist */
#define CMD_CLI_PLIST_CLEAR 0x26 /* clear the clients playlist */
#define CMD_GET_SERIAL  0x27 /* get an unique serial number */
#define CMD_PLIST_SET_SERIAL  0x28 /* assign a serial number to the server
	  playlist */
#define CMD_LOCK  0x29 /* acquire a lock */
#define CMD_UNLOCK  0x2a /* release the lock */
#define CMD_PLIST_GET_SERIAL  0x2b /* get the serial number of the server's
	  playlist */
#define CMD_GET_TAGS  0x2c /* get tags for the currently played file. */
#define CMD_TOGGLE_MIXER_CHANNEL  0x2d /* toggle the mixer channel */
#define CMD_GET_MIXER_CHANNEL_NAME  0x2e /* get the mixer channel's name */
#define CMD_GET_FILE_TAGS 0x2f  /* get tags for the specified file */
#define CMD_ABORT_TAGS_REQUESTS 0x30  /* abort previous CMD_GET_FILE_TAGS
	     requests up to some file */
#define CMD_CLI_PLIST_MOVE  0x31  /* move an item */
#define CMD_LIST_MOVE   0x32  /* move an item */



extern int __attribute__((format (printf, 3, 4)))
	mysnprintf (char *s, int n, const char *format, ...);
extern int send_int (int sock, int i);
extern int send_str (int sock, const char *str);
extern int get_int_noblock (int sock, int *i);
extern int get_int (int sock, int *i);
extern char *get_str (int sock) ;
extern void *xmalloc (const size_t size);
extern struct file_tags *recv_tags (int sock) ;
extern void event_push (struct event_queue *q, const int event, void *data);
extern struct file_tags *tags_dup (const struct file_tags *tags);
extern void free_tag_ev_data (struct tag_ev_response *d);
extern void file_info_reset (struct file_info *f);
extern char *xstrdup (const char *s);
extern void event_pop (struct event_queue *q);
extern struct event *event_get_first (struct event_queue *q);
extern void event_queue_init (struct event_queue *q);
extern int moc_server_connect ();
extern int ping_moc_server (int sock) ;
extern void event_queue_free (struct event_queue *q);
extern void clear_item_from_srv(int sock);
extern void sec_to_min(char * buff, const int seconds);
extern char *moc_build_title (const struct file_tags *tags);
extern void tags_free (struct file_tags *tags);
